package cn.anecansaitin.firecrafting.client.integration.jei;

import cn.anecansaitin.firecrafting.ModConstant;
import cn.anecansaitin.firecrafting.api.client.crafting.IJEIRecipeRender;
import cn.anecansaitin.firecrafting.api.common.crafting.IFireRecipe;
import cn.anecansaitin.firecrafting.client.util.RenderHelper;
import cn.anecansaitin.firecrafting.common.item.ModItems;
import cn.anecansaitin.firecrafting.common.util.MathHelper;
import com.mojang.blaze3d.vertex.PoseStack;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.forge.ForgeTypes;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory;
import net.minecraft.core.NonNullList;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.fluids.FluidStack;
import org.jetbrains.annotations.NotNull;
import oshi.util.tuples.Quartet;
import oshi.util.tuples.Triplet;

import java.util.List;

//JEI拓展 烈焰配方的GUI实现
public class FireCategories implements IRecipeCategory<IFireRecipe> {
    public static final ResourceLocation ID = new ResourceLocation(ModConstant.MOD_ID, IFireRecipe.TYPE_ID);
    private final TranslatableComponent title = new TranslatableComponent("firecrafting.jei.title");
    private final IDrawable icon;
    private final IDrawable background;
    private int tick = 200;
    private int index = 0;

    public FireCategories(IGuiHelper helper) {
        icon = helper.createDrawableIngredient(VanillaTypes.ITEM_STACK, new ItemStack(ModItems.FIRE_INTERFACE.get()));
        background = helper.createDrawable(ModConstant.JEI_GUI, 0, 0, 179, 85);
    }

    @Override
    public @NotNull Component getTitle() {
        return title;
    }

    @Override
    public @NotNull IDrawable getBackground() {
        return background;
    }

    @Override
    public @NotNull IDrawable getIcon() {
        return icon;
    }

    @SuppressWarnings("all")
    @Override
    public ResourceLocation getUid() {
        return ID;
    }

    @Override
    public @NotNull RecipeType<IFireRecipe> getRecipeType() {
        return new RecipeType<>(FireCategories.ID, IFireRecipe.class);
    }

    @SuppressWarnings("all")
    @Override
    public Class<? extends IFireRecipe> getRecipeClass() {
        return IFireRecipe.class;
    }

    @Override
    public void setRecipe(@NotNull IRecipeLayoutBuilder builder, IFireRecipe recipe, @NotNull IFocusGroup focuses) {
        //添加无序配方的标记
        builder.setShapeless();
        NonNullList<Ingredient> ingredients = recipe.getIngredients();
        //获取指定坐标圆心与半径的园上均匀分布的点
        int[][] circle = MathHelper.circle(37, 37, 35, ingredients.size(), 0);
        //根据坐标添加原料格子
        for (int i = 0, circleLength = circle.length; i < circleLength; i++) {
            int[] ints = circle[i];
            builder.addSlot(RecipeIngredientRole.INPUT, ints[0], ints[1]).addIngredients(ingredients.get(i));
        }
        //获取配方指定的render
        IJEIRecipeRender render = recipe.getRender();
        //从render中获取需要要添加的原料与产物
        for (Triplet<Object, Integer, Integer> inputItemSlot : render.getInputItemSlots(recipe)) {
            Object a = inputItemSlot.getA();
            if (a instanceof ItemStack) {
                builder.addSlot(RecipeIngredientRole.INPUT, inputItemSlot.getB(), inputItemSlot.getC()).addItemStack((ItemStack) a);
            } else if (a instanceof Ingredient) {
                builder.addSlot(RecipeIngredientRole.INPUT, inputItemSlot.getB(), inputItemSlot.getC()).addIngredients((Ingredient) a);
            } else if (a instanceof List<?> && ((List<?>) a).get(0) instanceof ItemStack) {
                builder.addSlot(RecipeIngredientRole.INPUT, inputItemSlot.getB(), inputItemSlot.getC()).addItemStacks((List<ItemStack>) a);
            }
        }
        for (Triplet<ItemStack, Integer, Integer> resultItemSlot : render.getResultItemSlots(recipe)) {
            builder.addSlot(RecipeIngredientRole.OUTPUT, resultItemSlot.getB(), resultItemSlot.getC()).addItemStack(resultItemSlot.getA());
        }
        for (Triplet<FluidStack, Integer, Integer> resultFluidSlot : render.getResultFluidSlots(recipe)) {
            builder.addSlot(RecipeIngredientRole.OUTPUT, resultFluidSlot.getB(), resultFluidSlot.getC()).addIngredient(ForgeTypes.FLUID_STACK, resultFluidSlot.getA());
        }
    }

    @Override
    public void draw(IFireRecipe recipe, @NotNull IRecipeSlotsView recipeSlotsView, @NotNull PoseStack stack, double mouseX, double mouseY) {
        //index和tick用于在gui内复数元素的轮流展示
        List<Block> fires = recipe.getFires();
        if (tick == 0) {
            index++;
            tick = 100;
        }
        if (index >= fires.size()) {
            index = 0;
        }
        //获取配方指定render
        IJEIRecipeRender render = recipe.getRender();
        //在火焰前绘制
        render.drawBeforeFire(recipe, stack, mouseX, mouseY);
        RenderHelper.renderGUIBlock(fires.get(index), stack, 37, 37);
        //在火焰后绘制
        render.drawAfterFire(recipe, stack, mouseX, mouseY);
        //绘制高亮
        for (Quartet<Integer, Integer, Integer, Integer> pos : render.getHighlight(recipe, mouseX, mouseY)) {
            RenderHelper.renderSlotHighlight(stack, pos.getA(), pos.getB(), pos.getC(), pos.getD(), 0, -2130706433);
        }
        tick--;
    }

    @Override
    public @NotNull List<Component> getTooltipStrings(@NotNull IFireRecipe recipe, @NotNull IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) {
        //获取配方指定render的tooltip
        List<Component> tip = recipe.getRender().getTooltip(recipe, mouseX, mouseY);
        if (mouseX >= 37 && mouseX < 53 && mouseY > 37 && mouseY < 53) {
            Block fire = recipe.getFires().get(index);
            tip.add(fire.getName());
        }
        return tip;
    }
}
